﻿using Abp;
using Abp.Dependency;
using Abp.Domain.Repositories;
using Abp.EntityFrameworkCore.EFPlus;
using Abp.Threading;
using Mt.Site.Core.WorkFlows.Design.DiyForm;
using Mt.Site.Core.WorkFlows.Enum;
using Mt.Site.Core.WorkFlows.Process;
using Mt.Site.Core.WorkFlows.Process.Entities;
using Mt.Site.Core.WorkFlows.Process.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Mt.Site.Core.WorkFlows.Diy.Plugin
{

    //TODO: 确认所有函数调用 都完成  ( 增加 作废，删除，恢复的相关函数，包括IWorkFlowManager 和 IWorkFlowSuperManager)
    public abstract class WorkFlowPluginFunctionsBase : ITransientDependency
    {
        public abstract string DisplayName { get; }
        public abstract string UniqeName { get; }

        public virtual IWorkFlowRollBackDiyService WorkFlowRollBackDiyService => null;

        /// <summary>
        /// 新建稿件后
        /// </summary>
        /// <returns></returns>
        public virtual Task AfterPaperCreatedAsync(IWorkFlowManager workFlowManager)
        {
            return AbpTaskCache.CompletedTask;
        }

        /// <summary>
        /// 稿件办结前
        /// </summary>
        /// <returns></returns>
        public virtual Task BeforeFinishedAsync(IWorkFlowManager workFlowManager)
        {
            return AbpTaskCache.CompletedTask;
        }
        /// <summary>
        /// 稿件办结后
        /// </summary>
        /// <returns></returns>
        public virtual Task AfterFinishedAsync(IWorkFlowManager workFlowManager)
        {
            return AbpTaskCache.CompletedTask;
        }

        /// <summary>
        /// 归档前
        /// </summary>
        /// <param name="workFlowManager"></param>
        /// <returns></returns>
        public virtual Task BeforeArchivedAsync(WorkFlowPaper paper)
        {
            return AbpTaskCache.CompletedTask;
        }

        /// <summary>
        /// 归档后
        /// </summary>
        /// <param name="workFlowManager"></param>
        /// <returns></returns>
        public virtual Task AfterArchivedAsync(Guid paperId)
        {
            return AbpTaskCache.CompletedTask;
        }


        /// <summary>
        /// 稿件删除前
        /// </summary>
        /// <returns></returns>
        public virtual Task BeforeDeletedAsync(IWorkFlowSuperManager workFlowManager)
        {
            return AbpTaskCache.CompletedTask;
        }

        /// <summary>
        /// 稿件删除后
        /// </summary>
        /// <returns></returns>
        public virtual Task AfterDeletedAsync(IWorkFlowSuperManager workFlowManager)
        {
            return AbpTaskCache.CompletedTask;
        }


        /// <summary>
        /// 稿件停办前
        /// </summary>
        /// <returns></returns>
        public virtual Task BeforeCanceledAsync(IWorkFlowSuperManager workFlowManager)
        {
            return AbpTaskCache.CompletedTask;
        }

        /// <summary>
        /// 稿件停办后
        /// </summary>
        /// <returns></returns>
        public virtual Task AfterCanceledAsync(IWorkFlowSuperManager workFlowManager)
        {
            return AbpTaskCache.CompletedTask;
        }


        /// <summary>
        /// 稿件由停办状态恢复前
        /// </summary>
        /// <returns></returns>
        public virtual Task BeforeRestoreAsync(IWorkFlowSuperManager workFlowManager)
        {
            return AbpTaskCache.CompletedTask;
        }

        /// <summary>
        /// 稿件由停办状态恢复后
        /// </summary>
        /// <returns></returns>
        public virtual Task AfterRestoreAsync(IWorkFlowSuperManager workFlowManager)
        {
            return AbpTaskCache.CompletedTask;
        }



        /// <summary>
        /// 稿件由办结状态恢复前
        /// </summary>
        /// <returns></returns>
        public virtual Task BeforeResumeExecuteAsync(IWorkFlowSuperManager workFlowManager,Guid paperId)
        {
            return AbpTaskCache.CompletedTask;
        }
        /// <summary>
        /// 稿件由停办状态恢复后
        /// </summary>
        /// <returns></returns>
        public virtual Task AfterResumeExecuteAsync(IWorkFlowSuperManager workFlowManager)
        {
            return AbpTaskCache.CompletedTask;
        }

        public virtual Task<string> GetWenhaoAsync(IWorkFlowHelper workFlowHelper, Guid paperId, Guid workFlowId)
        {
            return workFlowHelper.GetWenhaoAsync(paperId, workFlowId);
        }

        public virtual async Task TrySaveWenhaoAsync(
            IWorkFlowHelper workFlowHelper, 
            Guid paperId, 
            string newValue, 
            FormConfigItem fieldConfig,
            IWorkflowDefinition workflow)
        {
            var paper = await workFlowHelper.GetWorkFlowPaperAsync(paperId);
            paper.ChangeReferNumber(newValue);
        }

        public virtual bool CleanMsgWhenDrawback(IWorkFlowManager workFlowManager)
        {
            return false;
        }

        /// <summary>
        /// 表单保存前( 做表单验证 或保存自定义数据)
        /// </summary>
        /// <returns></returns>
        public virtual Task BeforeSuperSaveFormAsync(UpdateFormDataInput input, WorkFlowPaper paper, IWorkFlowSuperManager workFlowManager)
        {
            return AbpTaskCache.CompletedTask;
        }

        /// <summary>
        /// 表单保存后（保存自定义数据 或 其他操作）
        /// </summary>
        /// <returns></returns>
        public virtual Task AfterSuperSaveFormAsync(UpdateFormDataInput input, WorkFlowPaper paper, IWorkFlowSuperManager workFlowManager)
        {
            return AbpTaskCache.CompletedTask;
        }

        // 归档，打印
        public virtual Task AfterGetDataForReadOnlyAsync(GetFormDataOutput output)
        {                   
            return AbpTaskCache.CompletedTask;
        }

        public virtual async Task ResetRuntimeDataAsync(
           Guid paperId, IRepository<WorkFlowRunTime, long> workFlowRuntimeRepository, List<WorkFlowProcessDto> allData)
        {
            var userIds = allData.Select(c => c.UserId).Distinct().ToList();

            var newDataList = new List<WorkFlowRunTime>();

            foreach (var userId in userIds)
            {
                var firstItem = allData.Where(t => t.UserId == userId && (t.State == ActionState.Todo || t.State == ActionState.Related))
                        .OrderBy(t => t.State)  /*优先取待办*/
                        .ThenByDescending(t => t.OperationType)  /*优先取办理*/
                        .ThenByDescending(t => t.Severity)       /*同时存在多个待办任务时按优先级取*/
                        .FirstOrDefault();

                if (firstItem != null)
                {
                    var newItem = new WorkFlowRunTime
                    {
                        PaperId = paperId,
                        ProcessId = firstItem.Id,
                        State = (firstItem.State == ActionState.Todo ? RunTimeState.Todo : RunTimeState.Related),
                        UserId = userId,
                        StartTime = firstItem.StartTime
                    };
                    newDataList.Add(newItem);
                }
            }

            var oldDataList = await workFlowRuntimeRepository.GetAllListAsync(c => c.PaperId == paperId);

            foreach (var item in oldDataList)
            {
                if (newDataList.FirstOrDefault(
                    t => t.ProcessId == item.ProcessId && t.State == item.State && t.UserId == item.UserId && t.StartTime == item.StartTime) == null)
                {
                    await workFlowRuntimeRepository.DeleteAsync(item);
                }
            }

            foreach (var item in newDataList)
            {
                if (oldDataList.FirstOrDefault(
                    t => t.ProcessId == item.ProcessId && t.State == item.State && t.UserId == item.UserId && t.StartTime == item.StartTime) == null)
                {
                    await workFlowRuntimeRepository.InsertAsync(item);
                }
            }
        }

        public virtual async Task CleanRuntimeDataAsync(
            Guid paperId, IRepository<WorkFlowRunTime, long> workFlowRuntimeRepository)
        {
            await workFlowRuntimeRepository.BatchDeleteAsync(t => t.PaperId == paperId);
        }
    }
}
